home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / MCASM.RAR / MC_ASM.EXE / WROX_ASM / CH12 / FORMATS / GRFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-26  |  7.5 KB  |  314 lines

  1. // This program contains implementation of grfile.h
  2. // Written by Podvoysky E. & Kiselev J. CZ 1994.
  3. #pragma -ml
  4.  
  5. #include <stdio.h>
  6. #include <mem.h>
  7. #include <alloc.h>
  8. #include <dos.h>
  9. #include "common.h"
  10. #include "graph.h"
  11. #include "grfile.h"
  12. #include "manager.h"
  13.  
  14. #define GRF_BUFSIZE (1<<14) //size of internal buffer
  15.  
  16. long minheap = 70000L;
  17.  
  18. int get_bitsperpixel(image_type it,image_extention_type iet) {
  19. switch(it) {
  20. case MONOIMG : return 1;
  21. case COLOR16IMG : return 4;
  22. case GRAY256IMG:
  23. case COLOR256IMG: return 8;
  24. case TRUECOLORIMG:
  25.     switch(iet) {
  26.     case RGB15: return 15;
  27.     case RGB16: return 16;
  28.     default: return 24;
  29.     }
  30. }
  31. return(1);
  32. }
  33.  
  34.  
  35. graph_file_abstract::graph_file_abstract() {
  36. file_ok = usebuffer = FALSE;
  37. the_file = NULL;
  38. }
  39.  
  40. graph_file_abstract:: ~graph_file_abstract() {
  41.     if  (the_file) fclose(the_file);
  42.     if (usebuffer) delete buffer;
  43. }
  44.  
  45. void graph_file_abstract::init_buffer(BOOL usebuffer_) {
  46.     long pos;
  47.  
  48.     usebuffer = usebuffer_;
  49.     if (usebuffer) {
  50.         buff_offset = 0;
  51.         buffer = new BYTE[BUFF_SIZE];
  52.         }
  53.     else if ((file_ok) && (coreleft() > minheap + GRF_BUFSIZE)) {
  54.         pos = ftell(the_file);
  55.         fseek(the_file,0,SEEK_SET);
  56.         setvbuf(the_file, NULL, _IOFBF, GRF_BUFSIZE);
  57.         fseek(the_file,pos,SEEK_SET);
  58.         }
  59. }
  60.  
  61. long graph_file_abstract::image_size() {return(bytesperline*height);}
  62.  
  63. graph_file_reader::graph_file_reader(char *fname) {
  64.     file_ok = FALSE;
  65.     top_to_bottom = left_to_right = TRUE;
  66.     the_file = NULL;
  67.     source_line = NULL;
  68.     standart_line = NULL;
  69.     line_n = 0;
  70.     the_file = fopen(fname, "rb");
  71.     file_ok = (the_file != NULL);
  72.     source_ext_type = NO_EXTENTION;
  73. }
  74.  
  75. // if buffer is almost cleared
  76. // reads new portion of data
  77. void graph_file_reader::fresh_buffer() {
  78.     if (!usebuffer) return;
  79.     if(buff_offset > (BUFF_SIZE - 2*bytesperline)) {
  80.         memmove(buffer,&buffer[buff_offset],BUFF_SIZE-buff_offset);
  81.         fread(&buffer[BUFF_SIZE-buff_offset],buff_offset,1,the_file);
  82.         buff_offset = 0;
  83.         }
  84. }
  85.  
  86. void graph_file_reader::seek_start() {
  87.     fseek(the_file, data_begin, SEEK_SET);
  88.     line_n = top_to_bottom ? 0 : height-1;
  89.     if (usebuffer) {
  90.         fread(buffer, BUFF_SIZE, 1,the_file);
  91.         buff_offset = 0;
  92.     }
  93. }
  94.  
  95. int graph_file_reader::get_next_line() {return(-1);}
  96.  
  97. int graph_file_reader::get_stand_line() {
  98.     int result;
  99.     result = get_next_line();
  100.     if (result >= 0) line2standart(source_line,standart_line,width);
  101.     return(result);
  102. }
  103.  
  104. /***************  SAVER ***************************************/
  105.  
  106. graph_file_saver::graph_file_saver(char *fname, BOOL usebuffer_,
  107.             image_type dest_type_,
  108.             image_extention_type dest_ext_type_,
  109.             int width_,int height_,BGRpalette* pal) {
  110.     top_to_bottom = left_to_right = TRUE;
  111.     file_ok = FALSE;
  112.     the_file = NULL;
  113.     line_n = 0;
  114.     dest_type = dest_type_;
  115.     dest_ext_type = dest_ext_type_;
  116.     palette = (BGRpalette*)pal;
  117.     width = width_;
  118.     height = height_;
  119.     the_file = fopen(fname, "wb");
  120.     file_ok = (the_file != NULL);
  121.     init_buffer(usebuffer_);
  122. }
  123.  
  124. int graph_file_saver::put_next_line(BYTE *line) {return -1;}
  125.  
  126. void graph_file_saver::flush_buffer() {
  127.     if (!usebuffer) return;
  128.  
  129.     fwrite(buffer,buff_offset,1,the_file);
  130.     buff_offset = 0;
  131. }
  132.  
  133. int graph_file_saver::put_stand_line(BYTE *line) {
  134.     int result;
  135.     BYTE *tmp;
  136.     tmp = new BYTE [bytesperline+1];
  137.     line2standart(line,tmp,width);
  138.     result = put_next_line(tmp);
  139.     delete tmp;
  140.     return(result);
  141. }
  142.  
  143. image_keeper::image_keeper(memory_type where_,
  144.             image_type im_type_,
  145.             int width_,int height_,BGRcolortype * pal,
  146.             BOOL top_to_bottom_) {
  147.     long imagesize;
  148.     int i;
  149.  
  150.     width = width_; height = height_; top_to_bottom = top_to_bottom_;
  151.     left_to_right = TRUE;
  152.     line_n = top_to_bottom ? 0 : height-1;
  153.  
  154.     bytesperline = width;
  155.     switch(im_type_) {
  156.     case MONOIMG : im_type = MONOIMG;
  157.             bytesperline = (width+7) / 8;
  158.             break;
  159.     case COLOR16IMG :
  160.     case GRAY256IMG:
  161.     case COLOR256IMG:  im_type = COLOR256IMG;
  162.                break;
  163.     case TRUECOLORIMG: im_type = TRUECOLORIMG;
  164.                bytesperline *= 3;
  165.                break;
  166.     }
  167.     if  (im_type == COLOR256IMG) {
  168.         palette = new BGRcolortype[256];
  169.         memcpy(palette, pal, sizeof(BGRpalette));
  170.         }
  171.     else  palette = NULL;
  172.  
  173.     imagesize = (long)bytesperline*(long)height;
  174.  
  175.     where = where_;
  176.     if (where == UNKNOWN) {
  177.         if (coreleft() > imagesize + minheap) where = convRAM;
  178.         else if (EXM_initialized && (EXM_coreleft() > imagesize  + 0x10000L)) where = exRAM;
  179.         else where = DISK;
  180.     }
  181.  
  182.     switch (where) {
  183.     case convRAM:
  184.         lines = new BYTE* [height];
  185.         memset(lines,0,height*sizeof(BYTE *));
  186.         for (i = 0; i < height; i++) {
  187.             lines[i] =  new BYTE[bytesperline];
  188.             if (lines[i] == NULL) return;
  189.             }
  190.         file_ok = TRUE;
  191.         break;
  192.     case exRAM:
  193.         lines_ext = new USER_HANDLE[height];
  194.         bytesperline = ((bytesperline + 1) >> 1) << 1;
  195.         // make length even for better performance with XMS
  196.  
  197.         memset(lines_ext,0xFF,height*sizeof(USER_HANDLE));
  198.         for (i = 0; i < height; i++) {
  199.             lines_ext[i] =  EXM_alloc(bytesperline);
  200.             if (lines_ext[i] == NULL_HANDLE) return;
  201.             }
  202.         current_line = new BYTE[bytesperline];
  203.         file_ok = (current_line != NULL);
  204.         break;
  205.  
  206.     case    DISK:
  207.         lines = NULL;
  208.         tmp_filename = tempnam("c:","cz$");
  209.         the_file = fopen(tmp_filename, "w+b");
  210.  
  211.         file_ok = (the_file != NULL);
  212.         init_buffer(FALSE);
  213.         current_line = new BYTE[bytesperline];
  214.         file_ok = file_ok && (current_line != NULL);
  215.         break;
  216.     }
  217. }
  218.  
  219. image_keeper:: ~image_keeper() {
  220.     int i;
  221.     char *tmpptr;
  222.     switch (where) {
  223.     case convRAM:
  224.         for (i = height-1; i >= 0; i--) if (lines[i] != NULL) delete lines[i];
  225.         delete lines;
  226.         break;
  227.     case exRAM:
  228.         for (i = height-1; i >= 0; i--)
  229.             if (lines_ext[i] != NULL_HANDLE)  EXM_free(lines_ext[i]);
  230.         delete lines_ext;
  231.         break;
  232.  
  233.     case    DISK:  fclose(the_file);
  234.         tmpptr = tmp_filename;
  235.         asm {
  236.             push ds
  237.             lds dx,tmpptr
  238.             mov ah,0x41
  239.             int 21h
  240.             pop ds
  241.         }
  242.         free(tmp_filename);
  243.         break;
  244.  
  245.     default:
  246.         if (current_line != NULL) delete current_line;
  247.     }
  248.     if (palette != NULL) delete palette;
  249. }
  250.  
  251. void image_keeper::store_line(BYTE * source) {
  252.     if ((line_n >= height) || (line_n < 0)) return;
  253.     switch (where) {
  254.     case convRAM:
  255.         memcpy( lines[line_n], source, bytesperline);
  256.         break;
  257.  
  258.     case exRAM:
  259.         if (EXM_move_to_ext(lines_ext[line_n], source, 0, bytesperline))
  260.             file_ok = FALSE;
  261.         break;
  262.  
  263.     case    DISK:
  264.         fseek(the_file,0,SEEK_END);
  265.         fwrite(source,bytesperline,1,the_file);
  266.     }
  267.     if (top_to_bottom) line_n++; else line_n--;
  268. }
  269.  
  270. BYTE* image_keeper::give_line(int line_no) {
  271.     switch (where) {
  272.     case convRAM:
  273.         return(lines[line_no]);
  274.         // break;
  275.  
  276.     case exRAM:
  277.         if (line_n ==  line_no) return(current_line);
  278.         if (EXM_move_to_conv(current_line, lines_ext[line_no],0,bytesperline))
  279.             file_ok = FALSE;
  280.         line_n = line_no;
  281.         return(current_line);
  282.         // break;
  283.  
  284.     case    DISK:
  285.         if (line_n ==  line_no) return(current_line);
  286.         if (top_to_bottom) fseek(the_file,(long)line_no * bytesperline, SEEK_SET);
  287.         else fseek(the_file,(long)(height-1-line_no) * (long)bytesperline, SEEK_SET);
  288.         fread(current_line,bytesperline,1,the_file);
  289.         line_n = line_no;
  290.         return(current_line);
  291.         // break;
  292.       }
  293. }
  294.  
  295.  
  296. void image_keeper::replace_line(int line_no,BYTE * source) {
  297.     if ((line_no >= height) || (line_no < 0)) return;
  298.     switch (where) {
  299.     case convRAM:
  300.         memcpy( lines[line_no], source, bytesperline);
  301.         break;
  302.  
  303.     case exRAM:
  304.         if (EXM_move_to_ext(lines_ext[line_no], source, 0, bytesperline))
  305.         file_ok = FALSE;
  306.         break;
  307.  
  308.     case    DISK:
  309.         if (top_to_bottom) fseek(the_file,(long)line_no * bytesperline, SEEK_SET);
  310.         else fseek(the_file,(long)(height-1-line_no) * (long)bytesperline, SEEK_SET);
  311.         fwrite(source,bytesperline,1,the_file);
  312.     }
  313. }
  314.